﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YiLong.Framework.DataAccess.Config;
using YiLong.Framework.Config;
using System.IO;
using System.Data;
using System.Threading;
using YiLong.Framework.Serialization;

namespace YiLong.Framework.DataAccess
{
    public static class DataCommandManager
    {
        private static Dictionary<string, DatabaseConfig> _dictDatabase = new Dictionary<string, DatabaseConfig>();
        private static Dictionary<string, DataCommandConfig> _dictDataCommand = new Dictionary<string, DataCommandConfig>();
        //private static FileSystemWatcher _watcher;
        private static readonly object _locker = new object();
        static DataCommandManager()
        {
            LoadDataConfig();
        }

        //static void watcher_Changed(object sender, FileSystemEventArgs e)
        //{
        //    lock (_locker)
        //    {
        //        LoadDataConfig();
        //        Thread.Sleep(10 * 1000);
        //    }
        //}

        public static void AddConnStr(string aliasName, string providerName, string connStr)
        {
            if (!_dictDatabase.ContainsKey(aliasName))
            {
                _dictDatabase.Add(aliasName, new DatabaseConfig()
                {
                    Name = aliasName,
                    ProviderName = providerName,
                    ConnectionString = connStr
                });

            }
        }

        public static void LoadConnStr(string dbConfigName)
        {
            DatabaseConfigs dbConfigs = SerializeUtil.DeserializeXml<DatabaseConfigs>(dbConfigName);
            _dictDatabase.Clear();
            foreach (DatabaseConfig dbConfig in dbConfigs.Databases)
            {
                _dictDatabase.Add(dbConfig.Name, dbConfig);
            }
        }

        public static DataCommand GetDataCommand(string name)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentException("DataCommand name cannot be null or empty.");
            }
            if (!_dictDataCommand.ContainsKey(name))
            {
                throw new Exception(string.Format("DataCommand named \"{0}\" does not exist.", name));
            }
            DataCommandConfig dataCommandConfig = _dictDataCommand[name];
            if (!_dictDatabase.ContainsKey(dataCommandConfig.Database))
            {
                throw new Exception(string.Format("Database named \"{0}\" does not exist.", dataCommandConfig.Database));
            }

            DatabaseConfig dbConfig = _dictDatabase[dataCommandConfig.Database];
            return new DataCommand(dbConfig.ProviderName, dbConfig.ConnectionString, _dictDataCommand[name]);
        }

        //public static CustomDataCommand CreateCustomDataCommand(string databaseName
        //    , string commmandText
        //    , CommandType commandType = CommandType.Text
        //    , int commandTimeout = 1000)
        //{
        //    if (!_dictDatabase.ContainsKey(databaseName))
        //    {
        //        throw new Exception(string.Format("Database named \"{0}\" does not exist.", databaseName));
        //    }
        //    DatabaseConfig dbConfig = _dictDatabase[databaseName];
        //    return new CustomDataCommand(dbConfig.ProviderName, dbConfig.ConnectionString, commmandText, commandType, commandTimeout);
        //}

        private static void LoadDataConfig()
        {
            string baseDir = Directory.GetCurrentDirectory();//AppDomain.CurrentDomain.BaseDirectory;
            //load database instanse
            string dbConfigFile = Path.Combine(baseDir, ConfigManager.DataAccessConfig.DatabaseFile);
            if (File.Exists(dbConfigFile))
            {
                DatabaseConfigs dbConfigs = SerializeUtil.DeserializeXml<DatabaseConfigs>(dbConfigFile);
                _dictDatabase.Clear();
                foreach (DatabaseConfig dbConfig in dbConfigs.Databases)
                {
                    if (_dictDataCommand.ContainsKey(dbConfig.Name))
                    {
                        string errorMsg = string.Format("链接字符串键\"{0}\"已经存在，请检查Configs\\DatabaseConfigs.config。", dbConfig.Name);
                        throw new ArgumentException(errorMsg);
                    }
                    _dictDatabase.Add(dbConfig.Name, dbConfig);
                }
            }
            //load data command
            string dataConfigDir = Path.Combine(baseDir, ConfigManager.DataAccessConfig.DataConfigDir);
            if (Directory.Exists(dataConfigDir))
            {
                string[] dbFiles = Directory.GetFiles(dataConfigDir, "*.config", SearchOption.AllDirectories);
                _dictDataCommand.Clear();
                foreach (string fileName in dbFiles)
                {
                    DataCommandConfigs dataCommandConfigs = SerializeUtil.DeserializeXml<DataCommandConfigs>(fileName);
                    foreach (DataCommandConfig dataCommandConfig in dataCommandConfigs.DataCommands)
                    {
                        if (_dictDataCommand.ContainsKey(dataCommandConfig.Name))
                        {
                            string errorMsg = string.Format("SQL键\"{0}\"已经存在，请检查SQL配置文件。", dataCommandConfig.Name);
                            throw new ArgumentException(errorMsg);
                        }
                        _dictDataCommand.Add(dataCommandConfig.Name, dataCommandConfig);
                    }
                }
            }
            //_watcher = new FileSystemWatcher(dataConfigDir);
            //_watcher.Changed += new FileSystemEventHandler(watcher_Changed);
            //_watcher.IncludeSubdirectories = true;
            //_watcher.EnableRaisingEvents = true;
        }
    }
}
